﻿// // ******************************************************************
// //       /\ /|       @file       TranslateCommandHandler.cs
// //       \ V/        @brief      await29
// //       | "")       @author     Await, 285283010@qq.com
// //       /  |
// //      /  \\        @Modified   2025-03-01 21:03
// //    *(__\_\        @Copyright  Copyright (c) , 2025-02-23 10:02 Await
// // ******************************************************************

using System.Text;
using AutomaticSubtitles.Contracts.Entity;
using AutomaticSubtitles.Service.Application.Cahce.Queries;
using AutomaticSubtitles.Service.Application.Translate.Commands;
using AutomaticSubtitles.Service.Application.Translate.Interface.Queries;
using AutomaticSubtitles.Service.Application.Translate.Queries;
using AutomaticSubtitles.Service.BackgroundServices;
using AutomaticSubtitles.Service.DataAccess.Model;
using AutomaticSubtitles.Service.Domain.Translate;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;

namespace AutomaticSubtitles.Service.Application.Translate;

public class TranslateCommandHandler(
    ITranslateRepository repository,
    IEventBus eventBus,
    RedisClient redisClient,
    ILogger<TranslateCommandHandler> logger,
    IConfiguration configuration)
    : BaseAutoService
{
    [EventHandler(1)]
    public async Task Handler1(GetTranslationCommand command)
    {
        var obtainTranslatedContent = await TranslationDataSynchBackgroundService.GetObtainTranslatedContent(command.LanguageType, command.Value, command.TranslatedLanguageType);
        //翻译成功
        command.Result = string.Join("", obtainTranslatedContent.TranslatedSegments);
        command.IsDid = obtainTranslatedContent.AllTranslated;
        if (!obtainTranslatedContent.AllTranslated)
            command.SubtitleSegmentationData = obtainTranslatedContent; // 保存未翻译的段落信息，供后续处理
    }

    [EventHandler(2)]
    public async Task Handler2(GetTranslationCommand command)
    {
        if (command.IsDid) return;

        try
        {
            var hasUntranslatedSegments = false;
            // 遍历未翻译的段落，尝试从数据库查询
            foreach (var untranslatedSegment in command.SubtitleSegmentationData.UntranslatedSegments)
            {
                // 跳过分隔符
                if (Common.SplitRegex.IsMatch(untranslatedSegment.Value))
                    continue;

                // 从数据库查询翻译
                var translationResult = await repository.GetValueAsync(
                    command.LanguageType,
                    command.TranslatedLanguageType,
                    untranslatedSegment.Value
                );

                if (!string.IsNullOrWhiteSpace(translationResult.Value))
                {
                    // 找到翻译，更新结果
                    command.SubtitleSegmentationData.UpdateTranslatedID.Add(translationResult.Id!);
                    command.SubtitleSegmentationData.TranslatedSegments[untranslatedSegment.Key] = translationResult.Value;
                    // 从未翻译列表中移除
                    command.SubtitleSegmentationData.UntranslatedSegments.Remove(untranslatedSegment.Key);
                }
                else
                {
                    hasUntranslatedSegments = true;
                }
            }

            // 如果所有段落都已翻译，更新状态
            if (!hasUntranslatedSegments)
            {
                // 重建完整的翻译结果
                var resultBuilder = new StringBuilder();
                foreach (var segment in command.SubtitleSegmentationData.TranslatedSegments) resultBuilder.Append(segment);

                command.Result = resultBuilder.ToString();
                command.IsDid = true;
                logger.LogInformation($"--数据库查询完成翻译，原文长度: {command.Value.Length}, 结果长度: {command.Result.Length}");
            }
            else
            {
                logger.LogInformation($"--部分内容未找到翻译，需要继续处理: {command.SubtitleSegmentationData.UntranslatedSegments.Count} 个片段");
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, $"--数据库翻译查询失败: {command.Value}");
            throw;
        }
    }

    [EventHandler(3)]
    public async Task Handler3(GetTranslationCommand command)
    {
        try
        {
            // 确保SubtitleSegmentationData已初始化
            if (command.SubtitleSegmentationData == null)
            {
                logger.LogWarning("Handler3: 命令的SubtitleSegmentationData为空，正在初始化");
                command.SubtitleSegmentationData = new SubtitleSegmentationData
                {
                    TranslatedSegments = new List<string>(),
                    UntranslatedSegments = new Dictionary<int, string>()
                };
            }

            await AIDirectTranslation(command);
            if (command.IsDid) return;

            try
            {
                var batchSize = 5; // 可以根据API限制调整批量大小
                var batches = command.SubtitleSegmentationData.UntranslatedSegments
                    .Select((item, index) => new { Item = item, Index = index })
                    .GroupBy(x => x.Index / batchSize)
                    .Select(g => g.Select(x => x.Item));

                foreach (var batch in batches)
                {
                    var getExternalTranslation = new GetExternalTranslation(batch, command.LanguageType, command.TranslatedLanguageType); //调用外部翻译操作
                    await eventBus.PublishAsync(getExternalTranslation);
                    var externalTranslation = getExternalTranslation.Result;
                    if (externalTranslation == null) return;
                    foreach (var (index, translation) in externalTranslation)
                        command.SubtitleSegmentationData.TranslatedSegments[index] = translation;
                }

                // 重建完整的翻译结果
                var resultBuilder = new StringBuilder();
                foreach (var t in command.SubtitleSegmentationData.TranslatedSegments)
                {
                    if (string.IsNullOrWhiteSpace(t)) continue;
                    resultBuilder.Append(t);
                }

                command.Result = resultBuilder.ToString();
                command.IsAdd = true;

                // 记录翻译完成的日志
                logger.LogInformation($"--完成翻译，原文长度: {command.Value.Length}, 结果长度: {command.Result.Length}, 未翻译片段: {command.SubtitleSegmentationData.UntranslatedSegments.Count}");
                logger.LogInformation($"--原文：{command.Value},翻译:{command.Result}");
            }
            catch (Exception ex)
            {
                logger.LogError($"Handler3翻译批处理异常: {ex.Message}");
            }
        }
        catch (Exception ex)
        {
            logger.LogError($"Handler3执行异常: {ex.Message}\n{ex.StackTrace}");
        }
    }

    /// <summary>
    /// ai直接翻译
    /// </summary>
    /// <param name="command"></param>
    private async Task AIDirectTranslation(GetTranslationCommand command)
    {
        try
        {
            // 确保必要的属性已初始化
            if (command == null)
            {
                logger.LogError("AIDirectTranslation: command 参数为空");
                return;
            }

            // 初始化分段数据（如果为空）
            if (command.SubtitleSegmentationData == null)
            {
                logger.LogWarning("AIDirectTranslation: SubtitleSegmentationData 为空，正在初始化");
                command.SubtitleSegmentationData = new SubtitleSegmentationData
                {
                    TranslatedSegments = new List<string>(),
                    UntranslatedSegments = new Dictionary<int, string>()
                };
            }

            var translateOptions = new FirstAIQuery();
            await eventBus.PublishAsync(translateOptions);
            if (!translateOptions.Result) return;

            var getExternalTranslation = new GetExternalTranslation([new KeyValuePair<int, string>(1, command.Value)], command.LanguageType, command.TranslatedLanguageType, true);
            //调用外部翻译操作
            await eventBus.PublishAsync(getExternalTranslation);
            if (getExternalTranslation.Result == null)
            {
                logger.LogWarning("AIDirectTranslation: 外部翻译返回空结果");
                return;
            }

            // 重建完整的翻译结果
            var resultBuilder = new StringBuilder();
            foreach (var t in getExternalTranslation.Result) resultBuilder.Append(t.Item2);
            command.Result = resultBuilder.ToString();
            command.IsDid = true;
            command.IsAdd = true;
            command.IsCompulsory = true;

            // 记录翻译完成的日志
            logger.LogInformation($"--完成翻译，原文长度: {command.Value.Length}, 结果长度: {command.Result.Length}, 未翻译片段: {command.SubtitleSegmentationData.UntranslatedSegments.Count}");
            logger.LogInformation($"--原文：{command.Value},翻译:{command.Result}");
        }
        catch (Exception ex)
        {
            logger.LogError($"AIDirectTranslation执行异常: {ex.Message}\n{ex.StackTrace}");
            // 设置命令的状态以表明处理过程中出现了错误
            command.IsDid = false;
        }
    }


    [EventHandler(4)]
    public async Task Handler4(GetTranslationCommand command)
    {
        if (!command.IsAdd) return;
        try
        {
            if (command.SubtitleSegmentationData.TranslatedSegments.Count > 0 && !command.IsCompulsory)
                // 遍历未翻译的词和它们的翻译结果
                foreach (var untranslatedWord in command.SubtitleSegmentationData.UntranslatedSegments)
                {
                    // 跳过分隔符
                    if (Common.SplitRegex.IsMatch(untranslatedWord.Value))
                        continue;

                    // 获取对应的翻译结果
                    var translatedValue = command.SubtitleSegmentationData.TranslatedSegments[untranslatedWord.Key];

                    // 检查是否已存在相同的翻译
                    var existingTranslation = await repository.FindAsync(x =>
                        x.Value == untranslatedWord.Value &&
                        x.LanguageType == command.LanguageType &&
                        x.TranslatedLanguageType == command.TranslatedLanguageType);

                    if (existingTranslation != null)
                    {
                        command.UpdateTransData ??= new List<string>();
                        command.UpdateTransData.Add(existingTranslation.Id);
                        continue;
                    }

                    // 创建新的翻译记录
                    var translationRecord = new Auto_Translate(BasicsHelper.GetId())
                    {
                        LanguageType = command.LanguageType!,
                        Value = untranslatedWord.Value,
                        TranslatedLanguageType = command.TranslatedLanguageType,
                        TranslatedValue = translatedValue,
                        TriggerCount = 1,
                        CreateTime = DateTime.Now,
                        Source = command.Source ?? "ExternalService",
                        SourcePath = command.Path ?? "手动"
                    };
                    command.AddTransData ??= new List<Auto_Translate>();
                    command.AddTransData.Add(translationRecord);
                    logger.LogInformation($"--新翻译存: {untranslatedWord.Value} -> {translatedValue}");
                }

            // 创建新的翻译记录
            var translationRecord2 = new Auto_Translate(BasicsHelper.GetId())
            {
                LanguageType = command.LanguageType!,
                Value = command.Value,
                TranslatedLanguageType = command.TranslatedLanguageType,
                TranslatedValue = command.Result,
                TriggerCount = 1,
                CreateTime = DateTime.Now,
                Source = command.Source ?? "ExternalService",
                SourcePath = command.Path ?? "手动"
            };
            command.AddTransData ??= new List<Auto_Translate>();
            command.AddTransData.Add(translationRecord2);
            logger.LogInformation($"--新翻译存: {command.Value} -> {command.Result}");
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "--保存翻译记录失败");
            throw;
        }
    }


    [EventHandler]
    public async Task HandlerGetTranslationCommand(GetTranslationCommand command)
    {
        if (command.UpdateTransData != null && command.AddTransData == null && command.SubtitleSegmentationData.UpdateTranslatedID.Count != 0) return;
        if (command.AddTransData != null)
        {
            var addData = new List<Auto_Translate>();
            foreach (var item in command.AddTransData)
            {
                // 首先检查ID是否已存在
                var existingRecordById = await repository.FindAsync(item.Id);
                if (existingRecordById != null)
                {
                    // ID已存在，生成新的ID
                    logger.LogWarning($"ID已存在，重新生成ID: 原ID={item.Id}");
                    item.SetId(BasicsHelper.GetId());
                }

                // 检查相同内容的翻译是否已存在
                var autoTranslate = await repository.GetCountAsync(x =>
                    x.LanguageType == item.LanguageType && x.TranslatedLanguageType == item.TranslatedLanguageType && x.Value == item.Value);
                if (autoTranslate == 0) addData.Add(item);
            }

            var msg = $"--新翻译存: {addData.Count}条 重复{command.AddTransData.Count - addData.Count}条";
            logger.LogInformation(msg);
            try
            {
                await repository.AddDataAsync(addData);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "添加翻译记录时发生未知错误");
                throw;
            }

            command.AddTransData.Clear();
        }

        var guids = command.SubtitleSegmentationData.UpdateTranslatedID;
        if (command.UpdateTransData != null) guids.AddRange(command.UpdateTransData);
        // 更新触发次数
        var update = new List<Auto_Translate>();
        foreach (var item in guids)
        {
            var firstOrDefault = update.FirstOrDefault(x => x.Id == item);
            if (firstOrDefault != null)
            {
                firstOrDefault.TriggerCount++;
                continue;
            }

            var existingTranslation = await repository.FindAsync(item);
            if (existingTranslation == null) continue;
            existingTranslation.TriggerCount++;
            update.Add(existingTranslation);
        }

        var msg2 = $"--翻译更新: {update.Count}条";
        logger.LogInformation(msg2);

        try
        {
            await repository.UpdateDataAsync(update);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "更新翻译记录时发生错误");
            throw;
        }

        TranslationDataSynchBackgroundService.CacheUpdate(command.LanguageType!, command.TranslatedLanguageType);
    }

    [EventHandler]
    public async Task Handler(AddTranslateCommand command)
    {
        var autoTranslate = await repository.FindAsync(x =>
            x.Value == command.Data.value &&
            x.LanguageType == command.Data.languageType &&
            x.TranslatedLanguageType == command.Data.translatedLanguageType);

        if (autoTranslate != null)
            throw new Exception("已存在相同的翻译");

        var translate = command.Data.MapTo<Auto_Translate>();
        translate.CreateTime = DateTime.Now;
        translate.Source = command.Data.source ?? "手动";

        // 生成唯一ID并检查
        var newId = BasicsHelper.GetId();
        var existingById = await repository.FindAsync(newId);
        // 如果ID已存在，则重新生成
        if (existingById != null)
        {
            logger.LogWarning($"生成的ID已存在，重新生成: {newId}");
            newId = BasicsHelper.GetId();
        }

        translate.SetId(newId);

        try
        {
            await repository.AddAsync(translate);
            command.Result++;
        }
        catch (DbUpdateException ex) when (ex.InnerException is SqliteException sqlEx &&
                                           (sqlEx.Message.Contains("UNIQUE constraint failed") || sqlEx.SqliteErrorCode == 19))
        {
            logger.LogError(ex, $"添加翻译时发生唯一约束错误: ID={newId}");
            // 最后一次尝试，再生成一个新ID
            newId = BasicsHelper.GetId();
            translate.SetId(newId);
            await repository.AddAsync(translate);
            command.Result++;
        }
    }

    [EventHandler]
    public async Task Handler(DeleteTranslateCommand command)
    {
        var translate = await repository.FindAsync(command.Id);
        if (translate == null)
            throw new Exception("翻译不存在");

        // 同时从缓存中删除
        var cacheKey = $"translate:{translate.LanguageType}:{translate.TranslatedLanguageType}";
        var cacheValue = await redisClient.GetAsync<List<CacheKeyValue>>(cacheKey);

        if (cacheValue != null)
        {
            cacheValue.RemoveAll(x => x.Id == translate.Id);
            await redisClient.SetAsync(cacheKey, cacheValue);
        }

        await repository.RemoveAsync(translate);
        command.Result++;
    }

    [EventHandler]
    public async Task Handler(UpdateTranslateCommand command)
    {
        var translate = await repository.FindAsync(x => x.Id == command.Data.id);
        if (translate == null)
            throw new Exception("翻译不存在");

        // 更新实体
        translate.LanguageType = command.Data.languageType;
        translate.Value = command.Data.value;
        translate.TranslatedValue = command.Data.translatedValue;
        translate.TranslatedLanguageType = command.Data.translatedLanguageType;
        translate.TriggerCount = command.Data.triggerCount ?? 1;
        translate.Source = command.Data.source ?? "手动";
        translate.SourcePath = command.Data.sourcePath;

        await repository.UpdateAsync(translate);

        // 更新缓存
        var cacheKey = $"translate:{translate.LanguageType}:{translate.TranslatedLanguageType}";
        var cacheValue = await redisClient.GetAsync<List<CacheKeyValue>>(cacheKey);

        if (cacheValue != null)
        {
            var existingEntry = cacheValue.FirstOrDefault(x => x.Id == translate.Id);
            if (existingEntry != null)
            {
                existingEntry.Value = translate.Value;
                existingEntry.TranslatedValue = translate.TranslatedValue;
            }
            else
            {
                cacheValue.Add(new CacheKeyValue
                {
                    Id = translate.Id,
                    Value = translate.Value,
                    TranslatedValue = translate.TranslatedValue
                });
            }

            await redisClient.SetAsync(cacheKey, cacheValue);
        }

        command.Result++;
    }
}